﻿using AexoManager.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using log4net;
using log4net.Config;
using AexoManager.Helpers;
using AexoManager.Datos;
using AexoManager.BussinesLogic;


namespace AexoManager.Controllers
{
    public class ProduccionController : Controller
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(ProduccionController));

        #region Acciones

        public ActionResult Index()
        {
            try
            {
                var trabajosEnProceso = new BSRegistroProceso().ObtenerIniciados();
                var trabajosPausados = new BSRegistroProceso().ObtenerPausados(null, null);
                ViewBag.TrabajosIniciados = trabajosEnProceso;
                ViewBag.TrabajosPausados = trabajosPausados;
            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar esta accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar esta accion.");
            }
            return View();
        }

        public ActionResult RegistroTiempos()
        {

            RegistroTiemposViewModel unRegistro = new RegistroTiemposViewModel();
            try
            {

                IList<Proceso> procesos = new BSProceso().ObtenerProcesos();
                IList<Empleado> usuarios = new BSEmpleado().ObtenerEmpleados();
                IList<Parte> partes = new BSParte().ObtenerPartes();

                ViewBag.procesos = procesos;
                ViewBag.Usuarios = usuarios;
                ViewBag.Partes = partes;
                ViewBag.AccionBoton = "Comenzar";

            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error en la presentacion de REgistroTiempos", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar esta accion.");
            }
            return View(unRegistro);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Registro(AexoManager.Models.RegistroTiemposViewModel modelo)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Parte unaParte = new BSParte().Get(new Parte { Codigo = modelo.CodigoPieza });

                    var result = new BSRegistroProceso().ObtenerIniciados(unaParte, new Proceso { IdProceso = (int)modelo.IdProceso }, new Empleado { IdEmpleado = (int)modelo.IdEmpleado });

                    IList<Proceso> procesos = new BSProceso().ObtenerProcesos();
                    IList<Empleado> usuarios = new BSEmpleado().ObtenerEmpleados();
                    IList<Parte> partes = new BSParte().ObtenerPartes();

                    ViewBag.procesos = procesos;
                    ViewBag.Usuarios = usuarios;
                    ViewBag.Partes = partes;

                    //Si no esta registrado ningun proceso inconcluso para esta Parte
                    if (result.Count() == 0)
                    {
                        int idComienzo = ObtenerRegistroPausado(modelo, unaParte);

                        if (idComienzo == 0)
                        {
                            GuardarRegistro(modelo);
                            modelo = new RegistroTiemposViewModel();
                            ViewBag.AccionBoton = "Comenzar";
                        }
                        else
                        {
                            modelo.Reanudar = true;
                            modelo.ReadOnly = true;
                            modelo.IdComienzo = idComienzo;
                            //modelo.IDComienzo = 8;
                            return View("RegistroTiempos", modelo);
                        }
                    }
                    else
                    {
                        RegistroProceso unRegistro = result[0];

                        //Se registro el iniio de un proceso para una pieza
                        if (modelo.Inicio == null)
                        {
                            modelo = CargarModelo(unRegistro);
                            ViewBag.AccionBoton = "Terminar";
                        }
                        //Se esta registrando el fin de un proceso para una pieza
                        else
                        {
                            unRegistro.Parte = new Parte { Codigo = modelo.CodigoPieza };
                            TerminarRegistro(unRegistro);
                            //return RedirectToAction("RegistroTiempos");
                            return RedirectToAction("Index");
                        }
                        return View("RegistroTiempos", modelo);

                    }
                    //return RedirectToAction("RegistroTiempos");
                    return RedirectToAction("Index");
                }
            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar esta accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar esta accion.");
            }
            //return RedirectToAction("RegistroTiempos");
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Pausar(AexoManager.Models.RegistroTiemposViewModel modelo)
        {
            try
            {
                RegistroProceso unRegistro = new RegistroProceso();
                unRegistro.Parte = new Parte { Codigo = modelo.CodigoPieza };
                unRegistro.Finalizo = false;
                unRegistro.Fin = DateTime.Now;
                new BSRegistroProceso().ActualizarEstado(unRegistro);
                BSRegistroProceso.Confirmar();


                //context.RegistroProcesoUpdate(unRegistro, DateTime.Now, false);
                //context.Commit();

            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar la pausa de la accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar la pausa de la accion.");
            }
            //return RedirectToAction("RegistroTiempos");
            return RedirectToAction("Index");
        }

        [HttpGet]
        public ActionResult Pausar(string id)
        {
            try
            {
                RegistroProceso dtoRegistroProceso = new BSRegistroProceso().Get(Int32.Parse(id));
                dtoRegistroProceso.Finalizo = false;
                dtoRegistroProceso.Fin = DateTime.Now;
                new BSRegistroProceso().ActualizarEstado(dtoRegistroProceso);
                BSRegistroProceso.Confirmar();
            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar la pausa de la accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar la pausa de la accion.");
            }

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Reanudar(AexoManager.Models.RegistroTiemposViewModel modelo)
        {
            try
            {
                GuardarRegistro(modelo);
                //modelo = new RegistroTiemposViewModel();
                //ViewBag.AccionBoton = "Comenzar";

            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar la pausa de la accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar la pausa de la accion.");
            }
            return RedirectToAction("Index");
        }

        [HttpGet]
        public ActionResult Reanudar(string id)
        {
            try
            {
                RegistroProceso dtoRegistroProceso = new BSRegistroProceso().Get(Int32.Parse(id));
                int idComienzo = new BSRegistroProceso().MaxIdComienzo();

                RegistroProceso dtoRegistroProcesoNueva = new RegistroProceso
                {
                    Parte = dtoRegistroProceso.Parte,
                    Proceso = dtoRegistroProceso.Proceso,
                    Cantidad = dtoRegistroProceso.Cantidad,
                    Empleado = dtoRegistroProceso.Empleado,
                    IdComienzo = idComienzo,
                    Inicio = DateTime.Now
                };

                new BSRegistroProceso().Save(dtoRegistroProcesoNueva);
                BSParent.Confirmar();
            }
            catch (Exception ex)
            {
                log.Error("Ocurrio un error al registrar la pausa de la accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar la pausa de la accion.");
            }

            return RedirectToAction("Index");
        }

        public ActionResult Terminar(string id)
        {
            try
            {
                RegistroProceso unRegistro = new BSRegistroProceso().Get(Int32.Parse(id));
                TerminarRegistro(unRegistro);
            }
            catch (Exception ex)
            {

                log.Error("Ocurrio un error al registrar esta accion", ex);
                ModelState.AddModelError("ErrorMensaje", "Ocurrio un error al registrar esta accion.");
            }

            return RedirectToAction("Index");
        }

        #endregion

        #region Metodos privados

        /// <summary>
        /// Guarda un nuevo registro en la tabpa de RegistroProceso
        /// </summary>
        /// <param name="modelo">Modelo obtenido de la vista</param>
        private void GuardarRegistro(RegistroTiemposViewModel modelo)
        {
            try
            {
                int idComienzo;

                var unaParte = new BSParte().Get(new Parte { Codigo = modelo.CodigoPieza });

                /**********/
                idComienzo = modelo.IdComienzo;
                if (idComienzo == 0)
                {
                    idComienzo = new BSRegistroProceso().MaxIdComienzo();
                    modelo.IdComienzo = idComienzo + 1;
                }
                /**********/

                RegistroProceso registroGuardar = new RegistroProceso 
                {
                    Parte = unaParte,
                    Proceso = new Proceso { IdProceso = modelo.IdProceso },
                    Cantidad = modelo.Cantidad,
                    Empleado = new Empleado { IdEmpleado = (int)modelo.IdEmpleado },
                    IdComienzo = modelo.IdComienzo,
                    Inicio = DateTime.Now
                };

                new BSRegistroProceso().Save(registroGuardar);
                //context.RegistroProcesoSave(unaParte, modelo.IdProceso, (int)modelo.Cantidad, (int)modelo.IdUsuario, modelo.IdComienzo, DateTime.Now);
                BSParent.Confirmar();
                //context.Commit();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Carga un modelo de vista a partir del registro obtenido de la base de datos
        /// </summary>
        /// <param name="unRegistro">Registro obtenido del la BD</param>
        /// <returns></returns>
        private RegistroTiemposViewModel CargarModelo(RegistroProceso unRegistro)
        {
            try
            {
                RegistroTiemposViewModel modelo = new RegistroTiemposViewModel();
                modelo.IdProceso = (int)unRegistro.IdProceso;
                modelo.CodigoPieza = unRegistro.Parte.Codigo;
                modelo.Inicio = unRegistro.Inicio;
                modelo.Cantidad = unRegistro.Cantidad;
                modelo.IdEmpleado = unRegistro.IdEmpleado;
                modelo.ReadOnly = true;

                return modelo;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Hace un update en la tabla RegistroProceso con el campo Fin y el campo Finalizado
        /// </summary>
        /// <param name="modelo"></param>
        /// <param name="unRegistro"></param>
        private void TerminarRegistro(RegistroProceso unRegistro)
        {
            try
            {
                unRegistro.Finalizo = true;
                unRegistro.Fin = DateTime.Now;
                new BSRegistroProceso().ActualizarEstado(unRegistro);
                BSParent.Confirmar();
            }
            catch (Exception)
            {

                throw;
            }
        }

        private int ObtenerRegistroPausado(RegistroTiemposViewModel modelo, Parte unaParte)
        {
            int idComienzo;
            var registrosPausados = new BSRegistroProceso().ObtenerPausados(unaParte.IdParte, modelo.IdEmpleado, modelo.IdProceso);

            if (registrosPausados.Count() > 0)
            {
                var unRegistroPausado = registrosPausados.First<RegistroProceso>();
                idComienzo = (int)unRegistroPausado.IdComienzo;
                return idComienzo;
            }
            else
            {
                return 0;
            }

        }

        #endregion
    }
}
